From 8b26b0124aeddd11c92328e5a968c0f903ee1f0a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Mon, 1 Dec 2025 11:07:43 +0100 Subject: [PATCH] router: remove duplicated PIOs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit There can be duplicated PIOs if the user changed the assigned prefix length in the configuration. Link: https://github.com/openwrt/odhcpd/pull/336 Signed-off-by: Álvaro Fernández Rojas --- src/router.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/router.c b/src/router.c index 63bb3db..ef47d0f 100644 --- a/src/router.c +++ b/src/router.c @@ -526,6 +526,43 @@ static void router_add_ra_pio(struct interface *iface, pio->length); } +static void router_clear_duplicated_ra_pio(struct interface *iface) +{ + size_t pio_cnt = iface->pio_cnt; + char ipv6_str[INET6_ADDRSTRLEN]; + + for (size_t i = 0; i < iface->pio_cnt; i++) { + struct ra_pio *pio_a = &iface->pios[i]; + size_t j = i + 1; + + while (j < iface->pio_cnt) { + struct ra_pio *pio_b = &iface->pios[j]; + + if (pio_a->length == pio_b->length && + !memcmp(&pio_a->prefix, &pio_b->prefix, sizeof(struct in6_addr))) { + warn("rfc9096: %s: clear duplicated %s/%u", + iface->ifname, + inet_ntop(AF_INET6, &pio_a->prefix, ipv6_str, sizeof(ipv6_str)), + pio_a->length); + + if (j + 1 < iface->pio_cnt) + iface->pios[j] = iface->pios[iface->pio_cnt - 1]; + + iface->pio_cnt--; + } else { + j++; + } + } + } + + if (iface->pio_cnt != pio_cnt) { + struct ra_pio *new_pios = realloc(iface->pios, sizeof(struct ra_pio) * iface->pio_cnt); + + if (new_pios) + iface->pios = new_pios; + } +} + static void router_clear_expired_ra_pio(time_t now, struct interface *iface) { @@ -824,6 +861,8 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr } } + router_clear_duplicated_ra_pio(iface); + iov[IOV_RA_PFXS].iov_base = (char *)pfxs; iov[IOV_RA_PFXS].iov_len = pfxs_cnt * sizeof(*pfxs); -- 2.30.2